package mn.idax.exchange.otc.web;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import mn.idax.exchange.auth.bean.AuthInfo;
import mn.idax.exchange.auth.interfaces.AuthService;
import mn.idax.exchange.auth.util.AuthInfoUtils;
import mn.idax.exchange.auth.util.RSAEncrypt;
import mn.idax.exchange.common.bean.ResponseData;
import mn.idax.exchange.otc.constant.RequestUrlConstant;
import mn.idax.exchange.otc.domain.OTCBeneficiarysInfoRequest;
import mn.idax.exchange.otc.domain.OTCBeneficiarysRequest;
import mn.idax.exchange.otc.domain.OTCBeneficiarysUpdateDisplayDTO;
import mn.idax.exchange.otc.entity.OTCBeneficiarys;
import mn.idax.exchange.otc.entity.OTCSysDictionaryItem;
import mn.idax.exchange.otc.entity.User;
import mn.idax.exchange.otc.enums.DictEnum;
import mn.idax.exchange.otc.enums.OTCBeneficiarysEnum;
import mn.idax.exchange.otc.enums.response.OTCBeneficiarysResponseEnum;
import mn.idax.exchange.otc.enums.response.UserResponseEnum;
import mn.idax.exchange.otc.exception.IdaxException;
import mn.idax.exchange.otc.service.FileUrlService;
import mn.idax.exchange.otc.service.OTCBeneficiarysService;
import mn.idax.exchange.otc.service.OTCSysDictionaryItemService;
import mn.idax.exchange.otc.service.UserService;
import mn.idax.exchange.otc.service.impl.MemoryService;
import mn.idax.exchange.otc.util.*;
import mn.idax.exchange.otc.vo.BeneficiarysInfo;
import mn.idax.exchange.otc.vo.OTCBeneficiarysDelete;
import mn.idax.exchange.otc.vo.OTCBeneficiarysUpdateDisplay;
import mn.idax.exchange.otc.vo.SysPayTypeInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther: shihaiming
 * @Date: 2018/08/06
 * @Description:
 */
@Api(value = "收款账号信息", tags = {"收款账号信息"})
@RequestMapping(RequestUrlConstant.MODULE_BENEFICIARYS)
@RestController
public class OTCBeneficiarysController {

    @Autowired
    private OTCBeneficiarysService otcBeneficiarysService;

    @Autowired
    private UserService userService;

    @Autowired
    private OTCSysDictionaryItemService otcSysDictionaryItemService;

    @Autowired
    private AuthService authService;

    @Autowired
    private FileUrlService fileUrlService;

    /**
     * 获取用户的收款账号信息列表
     *
     * @param request
     * @throws Exception
     */
    @ApiOperation(value = "获取用户的收款账号信息列表", notes = "获取用户的收款账号信息列表，(shihaiming，自测通过)")
    @RequestMapping(value = RequestUrlConstant.BENEFICIARYS_LIST, method = RequestMethod.POST)
    public ResponseData list(HttpServletRequest request) throws Exception {
        // 获取登录用户信息
        AuthInfo authInfo = AuthInfoUtils.getCurrent();
        Integer userId = Optional.ofNullable(authInfo).map(a -> a.getId()).orElse(-1);
        List<BeneficiarysInfo> list = otcBeneficiarysService.selectPayTypeInfoByUserID(userId);
        return ResponseData.success(list);
    }

    /**
     * 创建收款账号信息
     *
     * @param beneficiarysRequest
     * @param request
     * @throws Exception
     */
    @ApiOperation(value = "创建收款账号信息", notes = "创建收款账号信息，(shihaiming，自测通过)")
    @RequestMapping(value = RequestUrlConstant.BENEFICIARYS_CREATE, method = RequestMethod.POST)
    public ResponseData create(@Valid @RequestBody OTCBeneficiarysRequest beneficiarysRequest,
                               HttpServletRequest request) throws Exception {

       if (!StringUtils.isEmpty(beneficiarysRequest.getAttachmenturl())){
           String attachmenturl = fileUrlService.subFilePath(beneficiarysRequest.getAttachmenturl());
           beneficiarysRequest.setAttachmenturl(attachmenturl);
       }

        //检查文件格式是否合法
        if (OTCBeneficiarysEnum.PayMethodEnum.TYPE_WEIXIN.getCode().equals(beneficiarysRequest.getDictitemid())
                && !FileUtils.isImage(beneficiarysRequest.getAttachmenturl())) {
            throw new IdaxException(OTCBeneficiarysResponseEnum.UPLOAD_FILE_TYPE_ILLEGAL.getCode());
        }
        //收款名称必传
//    	 if (StringUtils.isEmpty(beneficiarysRequest.getName())){
//			 throw new IdaxException(OTCBeneficiarysResponseEnum.ACCOUNT_NAME_NOT_NULL.getCode());
//		 }

        String privateKey = authService.getPrivateKey();
        String account = RSAEncrypt.decrypt(beneficiarysRequest.getAccount(),privateKey);
        LogUtils.info(this.getClass(),"decrypt account is " + account);
        beneficiarysRequest.setAccount(account);
        //zhagnhu 和收款名称长度
        if (account.length() > 25 || beneficiarysRequest.getName().length() > 25) {
            throw new IdaxException(OTCBeneficiarysResponseEnum.EXCEEDED_LENGTH_LIMIT.getCode());
        }

        //收款类型是银行卡时，银行名称与支行名称必传
        if (OTCBeneficiarysEnum.PayMethodEnum.TYPE_BANK.getCode().equals(beneficiarysRequest.getDictitemid())) {
            if (StringUtils.isBlank(beneficiarysRequest.getBankname())) {
                throw new IdaxException(OTCBeneficiarysResponseEnum.BANK_NAME_NOT_NULL.getCode());
            }
            if (beneficiarysRequest.getBankname().length() > 25 || beneficiarysRequest.getSubbranchbankname().length() > 25) {
                throw new IdaxException(OTCBeneficiarysResponseEnum.EXCEEDED_LENGTH_LIMIT.getCode());
            }
        }

        // 获取登录用户信息
        AuthInfo authInfo = AuthInfoUtils.getCurrent();
        Integer userId = Optional.ofNullable(authInfo).map(a -> a.getId()).orElse(-1);

        //判断用户是否实名 未实名不能添加
        User user = userService.getUserById(userId);
        /***登录密码验证**/
        boolean result = verifyPassword(beneficiarysRequest.getPassword(), user);
        if(!result){
            throw new IdaxException(UserResponseEnum.USER_PASSWORD_ERROR.getRespCode());
        }

        if (!user.getIscertificate()) {
            throw new IdaxException(UserResponseEnum.USER_NOT_CERTIFICATE.getRespCode());
        }

        if (beneficiarysRequest.getId() == null || beneficiarysRequest.getId().intValue() == 0) {

            //检查用户是否已绑定相应的账号信息，限制一种收款类型只能绑定一张
            List<OTCBeneficiarys> list = otcBeneficiarysService.selectByUserID(userId);
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    if (list.get(i).getDictitemid().equals(beneficiarysRequest.getDictitemid())) {
                        throw new IdaxException(OTCBeneficiarysResponseEnum.TRANSACTION_MODE_ALREADY_EXISTED.getCode());
                    }
                }
            }

            OTCBeneficiarys otcBeneficiarys = new OTCBeneficiarys();
            BeanUtils.copyProperties(beneficiarysRequest, otcBeneficiarys);

            Date currDate = DateUtils.getUTCNow();
            //id为自增字段
            otcBeneficiarys.setId(null);
            LogUtils.info(this.getClass(), "This user Surname is ****** " + user.getSurname() + "Name is ******" + user.getName());
            otcBeneficiarys.setName(beneficiarysRequest.getName());
            otcBeneficiarys.setCreatetime(currDate);
            otcBeneficiarys.setUpdatetime(currDate);
            otcBeneficiarys.setUserid(userId);
            //设置默认显示
            otcBeneficiarys.setIsdisplay(true);

            //支付宝与微信收款方式不需要填写此字段，默认赋值成account字段
//            if(StringUtils.isBlank(otcBeneficiarys.getName())) {
//            	otcBeneficiarys.setName(otcBeneficiarys.getAccount());
//            }

            otcBeneficiarysService.addOTCBeneficiarys(otcBeneficiarys);
        } else {
            update(beneficiarysRequest, user);
        }
        return ResponseData.success();
    }

    /**
     * 密码验证
     *
     * @param password
     * @param user
     * @return
     */
    private boolean verifyPassword(String password, User user) throws Exception {

        return CryptoUtils.verfifyPassword(user.getPassword(), password, user.getPasswordsalt());
    }
    /**
     * @throws
     * @Title: update
     * @Description: 修改收款账号信息
     * @param: @param beneficiarysRequest
     * @param: @return
     * @param: @throws Exception
     * @return: ResponseData
     */
    private ResponseData update(OTCBeneficiarysRequest beneficiarysRequest, User user) throws Exception {
        // 获取登录用户信息
        AuthInfo authInfo = AuthInfoUtils.getCurrent();
        Integer userId = Optional.ofNullable(authInfo).map(a -> a.getId()).orElse(-1);

        //检查是否属于该用户的收款交易方式
        OTCBeneficiarys otcBeneficiarys = otcBeneficiarysService.selectByPrimaryKey(beneficiarysRequest.getId());
        if (otcBeneficiarys != null && otcBeneficiarys.getUserid().equals(userId)) {

            //收款类型是银行卡时，银行名称与支行名称必传
//		   if(OTCBeneficiarysEnum.type_bank.getCode().equals(otcBeneficiarys.getDictitemid())) {
//			   if(StringUtils.isBlank(beneficiarysRequest.getBankname())) {
//			       throw new IdaxException(OTCBeneficiarysResponseEnum.BANK_NAME_NOT_NULL.getCode());
//			   }
//		   }

            //创建对象
            OTCBeneficiarys newOTCBeneficiarys = new OTCBeneficiarys();
            BeanUtils.copyProperties(beneficiarysRequest, newOTCBeneficiarys);
            newOTCBeneficiarys.setId(otcBeneficiarys.getId());
            newOTCBeneficiarys.setName(beneficiarysRequest.getName());
            newOTCBeneficiarys.setUpdatetime(DateUtils.getUTCNow());
            //修改时不能修改收款类型
            newOTCBeneficiarys.setDictitemid(otcBeneficiarys.getDictitemid());
            //设置默认显示
//            newOTCBeneficiarys.setIsdisplay(true);

            //支付宝与微信收款方式不需要填写此字段，默认赋值成account字段
//		 if(StringUtils.isBlank(newOTCBeneficiarys.getName())) {
//			   newOTCBeneficiarys.setName(newOTCBeneficiarys.getAccount());
//		 }

            otcBeneficiarysService.updateOTCBeneficiarys(newOTCBeneficiarys);
        } else {
            throw new IdaxException(OTCBeneficiarysResponseEnum.DATA_NOT_EXIST.getCode());
        }
        return ResponseData.success();
    }


    /**
     * 根据id获取用户的收款账号信息
     *
     * @param request
     * @throws Exception
     */
    @ApiOperation(value = "根据id获取用户的收款账号信息", notes = "根据id获取用户的收款账号信息，(shihaiming，自测通过)")
    @RequestMapping(value = RequestUrlConstant.BENEFICIARYS_INFO, method = RequestMethod.POST)
    public ResponseData info(@RequestBody OTCBeneficiarysInfoRequest otcBeneficiarysInfoRequest, HttpServletRequest request) throws Exception {
        //检查id
        if (otcBeneficiarysInfoRequest.getId() == null || otcBeneficiarysInfoRequest.getId() < 1) {
            throw new IdaxException(OTCBeneficiarysResponseEnum.ID_NOT_EXIST.getCode());
        }

        // 获取登录用户信息
        AuthInfo authInfo = AuthInfoUtils.getCurrent();
        Integer userId = Optional.ofNullable(authInfo).map(a -> a.getId()).orElse(-1);

        OTCBeneficiarys otcBeneficiarys = otcBeneficiarysService.selectByPrimaryKey(otcBeneficiarysInfoRequest.getId());
        if (otcBeneficiarys == null || !otcBeneficiarys.getUserid().equals(userId)) {
            throw new IdaxException(OTCBeneficiarysResponseEnum.DATA_NOT_EXIST.getCode());
        }
        //不返回用户的id
        otcBeneficiarys.setUserid(null);
        otcBeneficiarys.setAttachmenturl(fileUrlService.dealFileUrlAddress(otcBeneficiarys.getAttachmenturl()));
        return ResponseData.success(otcBeneficiarys);
    }


    @ApiOperation(value = "修改付款方式隐藏/展示", notes = "修改付款方式隐藏/展示，(jack_huang，自测通过)")
    @RequestMapping(value = RequestUrlConstant.BENEFICIARYS_UPDATEDISPLAY, method = RequestMethod.POST)
    public ResponseData updateDisplay(@RequestBody OTCBeneficiarysUpdateDisplayDTO OTCBeneficiarysUpdateDisplayDTO) {

        // 获取登录用户信息
        AuthInfo authInfo = AuthInfoUtils.getCurrent();
        Integer userId = Optional.ofNullable(authInfo).map(a -> a.getId()).orElse(-1);

        OTCBeneficiarysUpdateDisplay otcBeneficiarysUpdateDisplay = new OTCBeneficiarysUpdateDisplay(userId,
                OTCBeneficiarysUpdateDisplayDTO.getDictitemid(), OTCBeneficiarysUpdateDisplayDTO.getIsdisplay());

        Set<Integer> payTypeDTOS = MemoryService.PAYTYPEMAP.keySet();
        if (Objects.isNull(OTCBeneficiarysUpdateDisplayDTO.getDictitemid()) ||
                payTypeDTOS.stream().noneMatch(s -> OTCBeneficiarysUpdateDisplayDTO.getDictitemid().equals(s))){
            throw new IdaxException(OTCBeneficiarysResponseEnum.OTCBENEFICIARYS_WRONG.getCode());
        }

        if (otcBeneficiarysService.updateDisplay(otcBeneficiarysUpdateDisplay) < 0) {
            throw new IdaxException(OTCBeneficiarysResponseEnum.OTCBENEFICIARYS_DISPLAY_FAIL.getCode());
        }

        return ResponseData.success();
    }

    /**
     * 获取支付方式
     *
     * @param request
     * @return
     * @addDate: 2018.12.04 .jension
     */
    @ApiOperation(value = "获取支付方式集合", notes = "获取支付方式集合")
    @RequestMapping(value = RequestUrlConstant.BENEFICIARYS_PAYMODELIST, method = RequestMethod.POST)
    public ResponseData getPayModeList(HttpServletRequest request) {
        // 获取登录用户信息
        AuthInfo authInfo = AuthInfoUtils.getCurrent();
        Integer userId = Optional.ofNullable(authInfo).map(a -> a.getId()).orElse(-1);

        Map<String, Object> resultMap = Maps.newHashMap();
        //  已绑定的支付方式
        List<BeneficiarysInfo> existList = otcBeneficiarysService.selectPayTypeInfoByUserID(userId);

        // 所有的支付方式
        List<OTCSysDictionaryItem> allPayTypes = otcSysDictionaryItemService.listItem(DictEnum.PAY_TYPE.getCode());
        List<SysPayTypeInfo> noExistList = Lists.newArrayList();
        for (OTCSysDictionaryItem otcSysDictionaryItem : allPayTypes) {
            SysPayTypeInfo sysPayTypeInfo = new SysPayTypeInfo();
            BeanUtils.copyProperties(otcSysDictionaryItem,sysPayTypeInfo);
            sysPayTypeInfo.setPayTypeNation(OTCPayTypeNationUtils.getPayType(otcSysDictionaryItem.getItemvalue()));
            sysPayTypeInfo.setPayTypeIcon(OTCPayTypeNationUtils.getPayTypeIcon(otcSysDictionaryItem.getItemvalue()));
            noExistList.add(sysPayTypeInfo);
        }

        Map<Integer, OTCSysDictionaryItem> collect = noExistList.stream().collect(Collectors.toMap(OTCSysDictionaryItem::getItemvalue, sysDictionaryItem -> sysDictionaryItem));
        for (OTCBeneficiarys otcBeneficiarys : existList) {
            if (null != collect.get(otcBeneficiarys.getDictitemid())) {
                // 清除已经绑定的支付方式
                noExistList.remove(collect.get(otcBeneficiarys.getDictitemid()));
            }
        }
        resultMap.put("existList", existList);
        resultMap.put("noExistList", noExistList);
        return ResponseData.success(resultMap);
    }


    /**
     * 删除收款账号信息
     * @param request
     * @param otcBeneficiarysDelete
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "删除收款账号信息", notes = "删除收款账号信息")
    @RequestMapping(value = RequestUrlConstant.BENEFICIARYS_DELET, method = RequestMethod.POST)
    public ResponseData delete(HttpServletRequest request, @RequestBody OTCBeneficiarysDelete otcBeneficiarysDelete) throws Exception {
        // 获取登录用户信息
        AuthInfo authInfo = AuthInfoUtils.getCurrent();
        Integer userId = Optional.ofNullable(authInfo).map(a -> a.getId()).orElse(-1);

        boolean result = otcBeneficiarysService.deleteOTCBeneficiarys(otcBeneficiarysDelete.getId());
        if(result){
            return ResponseData.success();
        }
        return ResponseData.error(OTCBeneficiarysResponseEnum.OTCBENEFICIARYS_DELETE.getCode(),"delete beneficiarys error");
    }
}
